package com.treasure.infrastructure.domain.impl;

import com.treasure.domain.velocity.TemplateEngine;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.util.*;

/**
 * @author sunhongmin
 * @date 2022/9/1 17:26
 * @description
 */
@Service
public class TemplateEngineImpl implements TemplateEngine {

    public <T> String writeDocument(String templateName, T velocityContextBean) throws IOException, IllegalAccessException {
        VelocityContext context = new VelocityContext();
        Class<?> contextBeanClass = velocityContextBean.getClass();
        for (Field filed : contextBeanClass.getDeclaredFields()) {
            filed.setAccessible(true);
            context.put(filed.getName(), filed.get(velocityContextBean));
        }
        return velocityAnalizer(context, templateName);
    }

    public String writeDocument(String templateName, Map<String, Object> keyValue) throws IOException {
        VelocityContext velocityContext = new VelocityContext();
        for (Map.Entry<String, Object> entry : keyValue.entrySet()) {
            velocityContext.put(entry.getKey(), entry.getValue());
        }
        return velocityAnalizer(velocityContext, templateName);
    }

    private String velocityAnalizer(VelocityContext context, String templateName) throws IOException {
        //1.设置velocity的资源加载类
        Properties prop = new Properties();
        prop.put("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
        //2.加载velocity引擎
        Velocity.init(prop);
        //4.加载velocity模板
        Template template = Velocity.getTemplate(String.format("template/%s", templateName), "utf-8");
        //5.合并数据
        Writer writer = new StringWriter();
        template.merge(context, writer);
        //6.释放资源
        writer.close();
        return writer.toString();
    }
}
